package org.beetl.sql.core.mapping;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.beetl.sql2o.reflection.Pojo;
import org.beetl.sql2o.reflection.PojoMetadata;
import org.beetl.support.DefaultNameMapper;
import org.beetl.support.NameMapper;

public class PojoResultSetRowMapper implements ResultSetRowMapper<Object>, ResultSetExtractor<Object> {

 private Map<String, String> caseSensitiveColumnMappings = new HashMap<String, String>();;

 private Map<String, String> columnMappings = new HashMap<String, String>();;

 private final boolean caseSensitive;

 private final PojoMetadata metadata;

 public boolean isCaseSensitive() {
  return caseSensitive;
 }

 public Map<String, String> getColumnMappings() {
  if (this.isCaseSensitive()) {
   return this.caseSensitiveColumnMappings;
  } else {
   return this.columnMappings;
  }
 }

 public PojoResultSetRowMapper(@SuppressWarnings("rawtypes") Class returnType, boolean caseSensitive) {
  super();
  this.caseSensitive = caseSensitive;
  metadata = new PojoMetadata(returnType, this.isCaseSensitive(), this.getColumnMappings());
 }

 public PojoResultSetRowMapper(@SuppressWarnings("rawtypes") Class returnType) {
  this(returnType, false);
 }

 void setColumnMappings(Map<String, String> mappings) {
  this.caseSensitiveColumnMappings = new HashMap<String, String>();
  this.columnMappings = new HashMap<String, String>();

  for (Map.Entry<String, String> entry : mappings.entrySet()) {
   this.caseSensitiveColumnMappings.put(entry.getKey(), entry.getValue());
   this.columnMappings.put(entry.getKey().toLowerCase(), entry.getValue().toLowerCase());
  }
 }

 public PojoMetadata getMetadata() {
  return metadata;
 }

 NameMapper nameMapper = new DefaultNameMapper();

 public Object mapRow(ResultSet cursor, int index) throws Exception {
  Pojo pojo = new Pojo(metadata, this.isCaseSensitive());
  ResultSetMetaData meta = cursor.getMetaData();
  for (int i = 0; i < meta.getColumnCount(); i++) {
   String key = meta.getColumnName(i + 1);
   Object value = cursor.getObject(i + 1);
   // 将列名自动转换成属性名.
   String name = key;
   if (key.toUpperCase().equals(key)) {
    name = nameMapper.getPropertyName(key);
   }
   pojo.setProperty(name, value);
  }
  return pojo.getObject();
 }

 public Map<String, Object> mapObject(Object object) {
  Map<String, Object> mapper = new HashMap<String, Object>();
  for (Iterator<String> eachFields = getMetadata().getFields().keySet().iterator(); eachFields.hasNext();) {
   String field = eachFields.next();
   Object value = getMetadata().getValueOfProperty(field, object);
   if (value != null) {
    mapper.put(field, value);
   }
  }
  return mapper;
 }

 public Object extractData(ResultSet cursor) throws Exception {
  return mapRow(cursor, 1);
 }
}
